package com.lsh.service.impl;

import com.lsh.dao.RegisterDao;
import com.lsh.dao.UserDatumDao;
import com.lsh.dao.UserHeadPortraitDao;
import com.lsh.dao.UserTokenDao;
import com.lsh.domain.Register;
import com.lsh.domain.User;
import com.lsh.domain.UserDatum;
import com.lsh.domain.UserTokens;
import com.lsh.service.RegisterService;
import com.lsh.util.TokenUtil;
import org.apache.activemq.command.ActiveMQMapMessage;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.math.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 注册业务实现类
 * @author Administrator
 * @date 2019/11/07 21:47
 */
@Service
public class RegisterServiceImpl implements RegisterService {

    @Autowired
    RegisterDao registerDao;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    JmsTemplate jmsTemplate;

    @Autowired
    UserHeadPortraitDao userHeadPortraitDao;
    @Autowired
    UserTokenDao userTokenDao;
    @Autowired
    UserDatumDao userDatumDao;


    private static Destination destination_mail = new ActiveMQQueue("queue.register.email");
    private static Destination destination_phone = new ActiveMQQueue("queue.register.phone");

    /**
     * 验证邮箱是否可用（是否已注册）
     * @param email
     * @return
     */
    @Override
    public boolean checkEmail(String email) {
        int count = registerDao.findUserByEmail(email);
        return (count!=0) ? true : false;
    }

    /**
     * 验证邮箱注册的验证码的正确与否
     * @param code
     * @param token
     * @return
     */
    @Override
    public boolean checkEmailCode(String code, String token) {
        String correctCode = (String) redisTemplate.opsForValue().get(token);
        if(code.equals(correctCode)) return true;
        return false;
    }

    /**
     * 验证用户名是否可用（是否已被注册）
     * @param username
     * @return
     */
    @Override
    public boolean checkUsername(String username) {
        int count = registerDao.findUserByUsername(username);
        return (count!=0) ? true : false;
    }

    /**
     * 缓存用户信息信息
     * 发送激活邮件至队列
     * @param register
     */
    @Override
    public void saveUserAndSendEmail(Register register) {
        String authCode = RandomStringUtils.randomAlphanumeric(100);
        try {
            MapMessage mapMessage = new ActiveMQMapMessage();
            mapMessage.setString("email", register.getEmail());
            mapMessage.setString("username", register.getUsername());
            mapMessage.setString("authCode", authCode);
            jmsTemplate.convertAndSend(destination_mail, mapMessage);
            redisTemplate.opsForValue().set(authCode, register, 2*60*60, TimeUnit.SECONDS);
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建用户（邮箱注册方式）
     * @param authCode
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, timeout = 10)
    public boolean createUser(String authCode) {
        Register register = (Register) redisTemplate.opsForValue().get(authCode);
        if(register == null) return false;
        else{
            User user = new User();
            user.setUsername(register.getUsername());
            user.setPassword(register.getPassword());
            user.setEmail(register.getEmail());
            int result = registerDao.insertUserByUser(user);
            if(result == 1){
                int userId = user.getId();
                UserDatum userDatum = new UserDatum();
                userDatum.setNickname(register.getNickname());
                userDatum.setBirthday(register.getBirthday());
                userDatum.setSex(register.getGender());
                userDatum.setPosition(register.getJob());
                userDatum.setUid(userId);
                userDatumDao.saveByUserDatum(userDatum);
                userHeadPortraitDao.saveHeadPortrait(userId);
                UserTokens userTokens = new UserTokens();
                userTokens.setUid(userId);
                userTokens.setExpires(7200);
                userTokenDao.saveUserToken(userTokens);
                return true;
            }else
                return false;
        }
    }

    /**
     * 删除缓存注册用户信息
     * @param authCode
     */
    @Override
    public void removeUser(String authCode) {
        redisTemplate.delete(authCode);
    }

    /**
     * 检查手机号码是否可用（是否未被注册）
     * @param phone
     * @return
     */
    @Override
    public boolean checkPhone(String phone) {
        int count = registerDao.findUserByPhone(phone);
        return (count==0) ? true : false;
    }

    /**
     * 发送注册验证码
     * @param phone
     * @param codeTime
     * @return
     */
    @Override
    public boolean sendRegisterCode(String phone, int codeTime) {
        String code = RandomStringUtils.randomNumeric(5);
        try {
            MapMessage message = new ActiveMQMapMessage();
            message.setString("phone", phone);
            message.setString("code", code);
            jmsTemplate.convertAndSend(destination_phone, message);
            redisTemplate.opsForValue().set(phone, code, codeTime, TimeUnit.SECONDS);
            return true;
        } catch (JMSException e) {
            e.printStackTrace();
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 校验手机号码与验证码是否一致
     * @param phone
     * @param code
     * @return
     */
    @Override
    public boolean checkPhoneAndCode(String phone, String code) {
        String currentCode = (String) redisTemplate.opsForValue().get(phone);
        if(code.equalsIgnoreCase(currentCode)){
            redisTemplate.delete(phone);
            return true;
        }
        else
            return false;
    }

    /**
     * 创建用户（手机号码注册）
     * @param register
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, timeout = 30000)
    public boolean createUser(Register register) {
        if(register == null) return false;
        User user = new User();
        user.setUsername(register.getUsername());
        user.setPassword(register.getPassword());
        user.setMobile(register.getPhone());
        int result = registerDao.insertUserByUser(user);
        if(result == 1) {
            int userId = user.getId();
            userHeadPortraitDao.saveHeadPortrait(userId);
            UserDatum userDatum = new UserDatum();
            userDatum.setUid(userId);
            userDatum.setBirthday(register.getBirthday());
            userDatum.setPosition(register.getJob());
            userDatum.setNickname(register.getNickname());
            userDatum.setSex(register.getGender());
            userDatumDao.saveByUserDatum(userDatum);
            UserTokens userTokens = new UserTokens();
            userTokens.setUid(userId);
            userTokens.setExpires(7200);
            userTokenDao.saveUserToken(userTokens);
            return true;
        }else
            return false;
    }
}
